#include "CBattleMgr.h"
#include "MsgBattle.pb.h"
#include "../simpleconfig/CRoleInitCfg.h"
#include "../simpleconfig/CMonsterConfig.h"
#include "../partner/CUserPartner.h"
#include "../skill/CSkillMgr.h"
#include "../skill/CSkill.h"
#include "../skill/CSkillAffect.h"
#include "../skill/CSkillEffect.h"
#include "../role/CUserRole.h"
#include "../data/CPlayerOnlineData.h"
#include "../status/CStatusMgr.h"
#include "../mainctrl.h"
#include "CTRandomNum.h"
#include "../instance/CInstanceConfig.h"

int CBattleMgr::DealBattleScore(bool bIsLeft, int& iAttackScore,
        int& iDefendScore)
{
    iAttackScore = 0;
    iDefendScore = 0;

    int iIndex = 0;
    int iTeamHP = 0;
    int iTeamHPMax = 0;
    int iTurnTimes = 0;
    int iDefendRatio = 0;
    double dRatio = 0.0;

    if (bIsLeft)
    {
        iTurnTimes = BATTLE_INF->_pstRules->GetLeftTurnTimes();
    }
    else
    {
        iTurnTimes = BATTLE_INF->_pstRules->GetRightTurnTimes();
    }

    BATTLE_INF->_pstRoles->CalcBattleTotalHP(bIsLeft, iTeamHP, iTeamHPMax);

    CT_BATTLE(("战斗评分:是否左方(%d)出手次数(%d)剩余总血量(%d)初始总血量(%d)",
               bIsLeft,iTurnTimes,iTeamHP,iTeamHPMax));

    if (iTurnTimes <= 0 || iTurnTimes > MAX_INSTANCE_BATTLE_SCORE_COUNT)
    {
        iTurnTimes = MAX_INSTANCE_BATTLE_SCORE_COUNT;
    }

    iIndex = 
        CMainCtrl::m_pstMain->m_stInstanceMgr.FindBattleScoreConfig(iTurnTimes);
    if (iIndex < 0)
    {
        return ERROR_INSTANCE_EMPTY_CFG;
    }

    CBattleScoreConfigData& stAttackScore =
        CMainCtrl::m_pstMain->m_stInstanceMgr.GetBattleScoreConfig(iIndex);

    iAttackScore = stAttackScore.GetAttackScore();

    if (iTeamHPMax > 0)
    {
        dRatio = iTeamHP * 1.0;
        dRatio /= (iTeamHPMax * 1.0);
        dRatio *= 100;//百分比
        dRatio += 0.5;//四舍五入
        iDefendRatio = (int)dRatio;
    }

    if (iDefendRatio > MAX_INSTANCE_BATTLE_SCORE_COUNT)
    {
        iDefendRatio = MAX_INSTANCE_BATTLE_SCORE_COUNT;
    }
    else if (iDefendRatio <= 0)
    {
        iDefendRatio = 1;
    }

    iIndex = 
        CMainCtrl::m_pstMain->m_stInstanceMgr.FindBattleScoreConfig(
                iDefendRatio);
    if (iIndex < 0)
    {
        return ERROR_INSTANCE_EMPTY_CFG;
    }

    CBattleScoreConfigData& stDefendScore =
        CMainCtrl::m_pstMain->m_stInstanceMgr.GetBattleScoreConfig(iIndex);

    iDefendScore = stDefendScore.GetDefendScore();

    CT_BATTLE(("战斗评分:出手次数(%d)攻击得分(%d)血量百分比(%d)防御得分(%d)",
               iTurnTimes,iAttackScore,iDefendRatio,iDefendScore));

    return 0;
}

int CBattleMgr::DealBattleScore(MsgBattleScore& stBattleScore)
{
    int iRet = 0;
    int iAttackScore = 0;
    int iDefendScore = 0;

    //左方攻击分
    //左方防御分
    iRet = DealBattleScore(true, iAttackScore, iDefendScore);
    CT_RETURN(iRet);

    stBattleScore.set_left_attack_score(iAttackScore);
    stBattleScore.set_left_defend_score(iDefendScore);

    //右方攻击分
    //右方防御分
    iRet = DealBattleScore(false, iAttackScore, iDefendScore);
    CT_RETURN(iRet);

    stBattleScore.set_right_attack_score(iAttackScore);
    stBattleScore.set_right_defend_score(iDefendScore);

    return 0;
}

int CBattleMgr::DoBattle(MsgBattleResult& stMsgBattleRes)
{
    int iRet = 0;
    int iResult = 0;
#if 0
    iRet = _stRoundCtrl.InitRoundCtrl();
    CT_RETURN(iRet);

    BATTLE_INF->_pstVideo->Init();
    BATTLE_INF->_pstVideo->BattleBegin();

    BATTLE_INF->_pstVideo->CircleBegin(_stRoundCtrl.GetRoundNum() + 1);

    BATTLE_INF->_pstRules->DealAtBattleBegin();
#endif
    CBattleAction stVideoAct;
    stVideoAct._iA = -1;

    while (true)
    {
        if (_stActionCtrl.IsEmpty())
        {
            if (stVideoAct._iA >= 0)
            {
                BATTLE_INF->_pstVideo->TurnEnd(stVideoAct._iA);
            }

            bool bIsEnd = false;
            iRet = _stRules.CheckEnd(bIsEnd, iResult);
            CT_RETURN(iRet);
            if (bIsEnd)
            {
                BATTLE_INF->_pstVideo->CircleEnd(_stRoundCtrl.GetRoundNum() + 1);
                break;
            }

            _stRoundCtrl.NextTurn();

            if (_stRoundCtrl.IsCircleEnd())
            {
                BATTLE_INF->_pstVideo->CircleEnd(_stRoundCtrl.GetRoundNum());
                BATTLE_INF->_pstVideo->CircleBegin(_stRoundCtrl.GetRoundNum() + 1);
                _stRoundCtrl.SetCircleEnd(false);
            }
        }
        else
        {
            CBattleAction stAction;
            iRet = _stActionCtrl.GetAction(stAction);
            CT_RETURN(iRet);

            iRet = stAction.Do();
            CT_RETURN(iRet);

            if (stAction._iActionID == CBattleAction::ACTION_GET_TURN)
            {
                stVideoAct = stAction;
            }
        }
    }

    BATTLE_INF->_pstVideo->BattleEnd();

    BATTLE_INF->_pstVideo->WriteVideo(stMsgBattleRes);

    stMsgBattleRes.set_result(iResult);

    CT_BATTLE(("战斗结果(2平局 1左方胜 0左方败)=%d",stMsgBattleRes.result()));

    if (iResult == BATTLE_RESULT_TIE)
    {
        for (int i = 0; i < stMsgBattleRes.role_infos_size(); ++i)
        {
            stMsgBattleRes.mutable_role_infos(i)->set_result(BATTLE_RESULT_TIE);
        }
    }
    else
    {
        int iRoleID = 0;
        for (int i = 0; i < stMsgBattleRes.role_infos_size(); ++i)
        {
            iRoleID = (stMsgBattleRes.role_infos(i)).id();
            if (!BATTLE_INF->_pstRoles->IsValidRoleID(iRoleID))
            {
                continue;
            }
            CBattleRole& stRole = BATTLE_INF->_pstRoles->GetRole(iRoleID);
            if (iResult == BATTLE_RESULT_WIN)
            {
                stMsgBattleRes.mutable_role_infos(i)->set_result(
                    (stRole.IsLeft() ? BATTLE_RESULT_WIN : BATTLE_RESULT_LOST));
            }
            else
            {
                stMsgBattleRes.mutable_role_infos(i)->set_result(
                    (stRole.IsLeft() ? BATTLE_RESULT_LOST : BATTLE_RESULT_WIN));
            }
        }
    }

    //战斗评分
    stMsgBattleRes.clear_battle_score();
    MsgBattleScore* pstMsgBattleScore = stMsgBattleRes.mutable_battle_score();
    if (pstMsgBattleScore)
    {
        iRet = DealBattleScore((*pstMsgBattleScore));
        CT_RETURN(iRet);
    }
    else
    {
        CT_ERROR(("protobuf alloc MsgBattleScore fail"));
    }

    //战斗统计信息
    stMsgBattleRes.set_battle_circle(_stRoundCtrl.GetRoundNum() + 1);
    stMsgBattleRes.set_left_first((_stRoundCtrl.IsLeftFirst() ? 1 : 0));
    stMsgBattleRes.set_battle_type(GetBattleActType());
    stMsgBattleRes.set_actual_battle(1);

    CT_BATTLE(("战斗统计信息:左方先出手(%d)持续圈数(%d)战斗类型(%d)",
        stMsgBattleRes.left_first(),stMsgBattleRes.battle_circle(),
        stMsgBattleRes.battle_type()));

#ifdef _DEBUG
    //打印一下输出的战斗录像用于调试
    for (int i = 0; i < stMsgBattleRes.battle_infos_size(); ++i)
    {
        CTSizeString<100>  sVideo;
        for (int j = 0; j < stMsgBattleRes.battle_infos(i).battle_line_size();
                ++j)
        {
            sVideo.Cat("%d ",stMsgBattleRes.battle_infos(i).battle_line(j));
        }

        CT_BATTLE(("%s",sVideo.Get()));
    }
#endif

    return 0;
}

int CBattleMgr::TransBattleMsg(MsgBattleResult& stMsgBattleRes)
{
    int iIndex = 0;
    int iGridPos = 0;
    CTSizeString<MAX_BATTLE_OBJ_NAME_LEN> szObjName;
    for (int i = 0; i < BATTLE_INF->_pstRoles->GetRoleCount(); ++i)
    {
        CBattleRoleData& stRoleData = BATTLE_INF->_pstRoles->GetRoleBase(i);

        MsgRoleInfoAtFight* pstRoleInfo = stMsgBattleRes.add_role_infos();
        if (!pstRoleInfo){continue;}

        szObjName.Set("");

        pstRoleInfo->set_id(i);
        iGridPos = stRoleData._bIsLeft ? stRoleData._iGridPos : MAX_BATTLE_GRIDS - 1 - stRoleData._iGridPos;
        pstRoleInfo->set_pos(iGridPos);
        pstRoleInfo->set_hp(stRoleData._iHP);
        pstRoleInfo->set_cp(stRoleData._iCourage);
        pstRoleInfo->set_ap(stRoleData._iAnger);
        pstRoleInfo->set_hp_max(stRoleData._iHPMax);
        pstRoleInfo->set_cp_max(stRoleData._iCourageMax);
        pstRoleInfo->set_ap_max(stRoleData._iAngerMax);
        
        pstRoleInfo->set_is_left((stRoleData._bIsLeft ? BATTLE_TEAM_LEFT : BATTLE_TEAM_RIGHT));
        pstRoleInfo->set_is_male((stRoleData._bIsMale ? 1 : 0));
        pstRoleInfo->set_career(stRoleData._ucCareer);
        pstRoleInfo->set_level(stRoleData._shLevel);

        pstRoleInfo->set_turn_order(stRoleData._stAttr.GetAttr(EXT_ATTR_TURN_ORDRE));

        if (GAME_OBJ_TYPE_SERVER_MONSTER_FRONT_ROLE == stRoleData._chType)
        {
            pstRoleInfo->set_type(GAME_OBJ_TYPE_PLAYER);
            stRoleData._chType = GAME_OBJ_TYPE_MONSTER;
        }
        else
        {
            pstRoleInfo->set_type(stRoleData._chType);
        }

        //如果是主角此值为GID
        //如果是伙伴此值为伙伴配置ID
        //如果是怪物此值为怪物配置ID
        pstRoleInfo->set_act_id((int)stRoleData._uiObjID);

        pstRoleInfo->set_mount_id((int)stRoleData._uiMountID);

        if (stRoleData._uiWingID > 0)
        {
            pstRoleInfo->set_wing_id(stRoleData._uiWingID);
        }

        if (stRoleData._uiDressID > 0)
        {
            pstRoleInfo->set_dress_id(stRoleData._uiDressID);
        }

        if (stRoleData._sObjName.GetDataLen() > 0)
        {
            pstRoleInfo->set_name(stRoleData._sObjName());
        }
        else if (GAME_OBJ_TYPE_PLAYER == stRoleData._chType)
        {
            iIndex = CMainCtrl::m_pstMain->m_stPlayerBaseInfoHash.HashFind(stRoleData._uiObjID);
            if (iIndex >= 0)
            {
                CPlayerBaseInfo& stPlayerBase = CMainCtrl::m_pstMain->m_stPlayerBaseInfoHash[iIndex];
                szObjName.Set("%s", stPlayerBase._sRoleName());
            }
            else
            {
                CT_WARNING(("Can find role(%u) base info for role name",stRoleData._uiObjID));
            }

            iIndex = CMainCtrl::m_pstMain->m_stPlayerOnlineDataHash.HashFind(stRoleData._uiObjID);
            if (iIndex >= 0)
            {
                CPlayerOnlineData& stPlayerOnline = CMainCtrl::m_pstMain->m_stPlayerOnlineDataHash[iIndex];
                pstRoleInfo->clear_pet();
                MsgPetBriefInfo* pstPetBriefInfo = pstRoleInfo->mutable_pet();
                stPlayerOnline._stUserPet.GetPetBriefInfo((*pstPetBriefInfo));
            }
            else
            {
                CT_WARNING(("Can find role(%u) base info for role name",stRoleData._uiObjID));
            }

            pstRoleInfo->set_name(szObjName());
        }

        CT_BATTLE(("BattleID(%d) ObjType(1:主角 2:伙伴 3:怪物 %d) ObjID(%d)",i,stRoleData._chType,(int)stRoleData._uiObjID));
        
        //装备
        (*pstRoleInfo).add_equips(0);//因为保证equip pos一致 其从1开始 这里增加一个0
        for (int i = 0; i < stRoleData._stEquip._auiPlayerEquip.Size(); ++i)
        {
            (*pstRoleInfo).add_equips(stRoleData._stEquip._auiPlayerEquip[i]);
        }
    
        //技能
        if (stRoleData._stNormalSkill.GetID() > 0)
        {
            (*pstRoleInfo).add_skills(stRoleData._stNormalSkill.GetID());
        }
        if (stRoleData._stMagicSkill.GetID() > 0)
        {
            (*pstRoleInfo).add_skills(stRoleData._stMagicSkill.GetID());
        }
    }

    return 0;
}

int CBattleMgr::ProcessBattle(MsgBattleResult& stMsgBattleRes)
{
    int iRet = 0;

    //注意必须先初始化参战个体再初始化地图 战斗地图需且仅需初始化一次
    iRet = BATTLE_INF->_pstMap->InitBattleMap();
    CT_RETURN(iRet);

    iRet = _stRoundCtrl.InitRoundCtrl();
    CT_RETURN(iRet);

    BATTLE_INF->_pstVideo->Init();

    BATTLE_INF->_pstVideo->BattleBegin();

    BATTLE_INF->_pstVideo->CircleBegin(_stRoundCtrl.GetRoundNum() + 1);

    //拷贝战斗个体信息给前端
    iRet = TransBattleMsg(stMsgBattleRes);
    CT_RETURN(iRet);

    //状态处理 STATUS_TRIGGER_ENTER_BATTLE //进入战斗时触发
    for(int i = 0; i < BATTLE_INF->_pstRoles->GetRoleCount(); ++i)
    {
        CBattleRole& stBattleRole = BATTLE_INF->_pstRoles->GetRole(i);
        CBattleRoleData& stRoleData = stBattleRole.GetRoleBase();
        CPlayerAttr& stBattleAttr = stBattleRole.GetBattleAttr();
        stBattleAttr.Clear();

        iRet = CMainCtrl::m_pstMain->m_stStatusMgr.StatusSkillAffect(
            stBattleRole, CStatusMgr::STATUS_TRIGGER_ENTER_BATTLE, 0);
        if (iRet)
        {
            CT_WARNING(("calc object(type=%d objid=%u) status attr error(%d)",
                stRoleData._chType, stRoleData._uiObjID, iRet));
        }
#if 0
        //状态一般不会修改二级属性中的HP属性 实际上是直接修改_iHP
        if (stBattleAttr.GetAttr(EXT_ATTR_HP) > 0)
        {
            stRoleData._iHP += stBattleAttr.GetAttr(EXT_ATTR_HP);//持续战斗不重置
            stRoleData._iHPMax = stRoleData._stAttr.GetAttr(EXT_ATTR_HP) +
                stBattleAttr.GetAttr(EXT_ATTR_HP);
        }
#endif
    }

    //处理一进战斗就怒气满情况需要输出怒气满状态
    BATTLE_INF->_pstRules->DealAtBattleBegin();

    iRet = DoBattle(stMsgBattleRes);
    CT_RETURN(iRet);
    
    return 0;
}

int CBattleMgr::TransPlayerAndPartner(CPlayerBaseInfo& stPlayerBase,
        CPlayerDetailInfo& stPlayerDetail, CPlayerOnlineData& stPlayerOnline,
        CBattleRoleList& stRoleList, bool bIsLeft)
{
    int iRet = 0;
    iRet = TransMatrixPartner(stPlayerBase, stPlayerDetail, stPlayerOnline,
        stRoleList, bIsLeft);
    CT_RETURN(iRet);

    CBattleRoleData stRoleData;
    iRet = TransPlayer(stPlayerBase, stPlayerDetail, stPlayerOnline, stRoleData,
        bIsLeft);

    iRet = stRoleList._astRoleData.AddOneItem(stRoleData);
    if (iRet < 0) {CT_WARNING(("transform player and partner error(%d)",iRet));}

    return 0;
}

int CBattleMgr::TransPlayer(CPlayerBaseInfo& stPlayerBase,
        CPlayerDetailInfo& stPlayerDetail, CPlayerOnlineData& stPlayerOnline,
        CBattleRoleData& stRoleData, bool bIsLeft)
{
    stRoleData.Clear();//必须执行

    int iRet = 0;
    int iIndex = 0;
    char chPos = 0;
    char chOrder = 0;

    iRet = CMainCtrl::m_pstMain->m_stMatrixMgr.GetPlayerPosAndOrder(
        stPlayerBase, stPlayerDetail, chPos, chOrder);
    CT_RETURN(iRet);

    CPlayerAttr& stRoleAttr = stPlayerOnline._stUserRole.GetAttr();

    stRoleData._bAngerOpen = CMainCtrl::m_pstMain->m_stCommConfigLoader.IsOpen(
        SYS_OPEN_COND_ID_35, stPlayerBase, stPlayerOnline);

    stRoleData._bIsLeft = bIsLeft;
    stRoleData._bIsMale = (1 == stPlayerBase._ucIsMale ? true : false);
    stRoleData._chType = GAME_OBJ_TYPE_PLAYER;
    stRoleData._iGridPos = chPos;
    stRoleData._ucOrder = chOrder;
    stRoleData._ucCareer = stPlayerBase._ucCareer;
    stRoleData._shLevel = stPlayerBase._shLevel;
    stRoleData._iHP = stRoleAttr.GetAttr(EXT_ATTR_HP);
    stRoleData._iHPMax = stRoleAttr.GetAttr(EXT_ATTR_HP);
    stRoleData._iAnger = stRoleAttr.GetAttr(EXT_ATTR_ACT_ANGER);
    stRoleData._iAngerMax = MAX_ROLE_ANGER;
    stRoleData._iCourage = MAX_ROLE_COURAGE;
    stRoleData._iCourageMax = MAX_ROLE_COURAGE;

    stRoleData._uiWingID = stPlayerOnline._uiNowWing;
    stRoleData._uiDressID = stPlayerOnline._uiNowDress;

    //如果是角色此值为角色GID
    //如果是伙伴此值为伙伴配置ID
    //如果是怪物此值为怪物配置ID
    stRoleData._uiObjID = stPlayerBase._uiGID;
    stRoleData._sObjName.Set("%s", stPlayerBase._sRoleName());

    unsigned short usEquipCfgID = 0;
    for (int i = 0; i < stPlayerDetail._stPlayerEquip._auiPlayerEquip.Size(); ++i)
    {

        if (stPlayerDetail._stPlayerEquip._auiPlayerEquip[i] > 0)
        {
            iRet = CMainCtrl::m_pstMain->m_stEquipMgr.GetConfigIdByEquipId(
                stPlayerDetail._stPlayerEquip._auiPlayerEquip[i], usEquipCfgID);
            if (!iRet)
            {
                stRoleData._stEquip.SetEquip(usEquipCfgID, i+1);
            }
        }
    }

    stRoleData._stAttr = stRoleAttr;

    stRoleData._stNormalSkill = stPlayerOnline._stUserRole.GetNormalSkill();

    if (CMainCtrl::m_pstMain->m_stCommConfigLoader.IsOpen(SYS_OPEN_COND_ID_37,
            stPlayerBase, stPlayerOnline))
    {
        stRoleData._stMagicSkill = stPlayerOnline._stUserRole.GetMagicSkill();
        stRoleData._iAngerMax = stRoleData._stMagicSkill.GetUseAnger();
    }

    //状态列表:职业特性
    iIndex = CMainCtrl::m_pstMain->m_stRoleConfigMgr.FindRoleInitCfg(
        stRoleData._ucCareer);
    if (iIndex < 0)
    {
        CT_WARNING(("no role init config for career(%d)",stRoleData._ucCareer));
        return ERROR_ROLE_INIT_EMPTY_CFG;
    }

	CRoleInitCfgData& stRoleInitData =
        CMainCtrl::m_pstMain->m_stRoleConfigMgr.GetRoleInitCfg(iIndex);

    iRet = CMainCtrl::m_pstMain->m_stStatusMgr.GetStatusList(
        stRoleInitData._iStatusGroupID, stRoleData._stStatusList);
    CT_RETURN(iRet);

    //状态列表:秘宝
    CMainCtrl::m_pstMain->m_stTreasureMgr.GetTreasureStatusList(
        GAME_OBJ_TYPE_PLAYER, stPlayerDetail._uiGID,
        stPlayerDetail, stRoleData._stStatusList);

    //状态列表:状态Hash
    CMainCtrl::m_pstMain->m_stStatusMgr.GetStatusList(stPlayerDetail._uiGID,
        stRoleData._stStatusList, GetBattleActType());

    //坐骑状态
    CMainCtrl::m_pstMain->m_stMountMgr.GetBattleStatus(GAME_OBJ_TYPE_PLAYER,
        stPlayerOnline, stRoleData._stStatusList);

    return 0;
}

int CBattleMgr::TransMatrixPartner(CPlayerBaseInfo& stPlayerBase,
        CPlayerDetailInfo& stPlayerDetail, CPlayerOnlineData& stPlayerOnline,
        CBattleRoleList& stRoleList, bool bIsLeft)
{
    int iRet = 0;
    int iIndex = 0;
    int iGridPos = 0;

    stRoleList.Clear();//必须执行

    char chMainMatrix = stPlayerDetail._stPlayerMatrix._chMainMatrix;
    CMatrixList& stMatrixList = stPlayerDetail._stPlayerMatrix._astMatrixData[chMainMatrix];
    for (int i = 0; i < stMatrixList._astMatrixList.Size(); ++i)
    {
        if (GAME_OBJ_TYPE_PARTNER != stMatrixList._astMatrixList[i]._chType)
        {
            continue;
        }
        iIndex = stPlayerDetail._stUserPartner.FindActData((short)stMatrixList._astMatrixList[i]._uiID);
        if (iIndex < 0)
        {
            continue;
        }
        CPartnerActData& stActData = stPlayerDetail._stUserPartner.GetPartnerActData(iIndex);

        iIndex = stPlayerOnline._stUserPartner.FindPartner((short)stMatrixList._astMatrixList[i]._uiID);
        if (iIndex < 0)
        {
            CT_ERROR(("Can find matrix(%d) partner(%d)",
                        stPlayerDetail._stPlayerMatrix._chMainMatrix,
                        (short)stMatrixList._astMatrixList[i]._uiID));
            continue;
        }
        CPartnerUnit& stPartner = stPlayerOnline._stUserPartner.GetPartner(iIndex);

        iIndex = CMainCtrl::m_pstMain->m_stPartnerMgr.FindPartnerCfg((short)stMatrixList._astMatrixList[i]._uiID);
        if (iIndex < 0)
        {
            continue;
        }
        CPartnerCfgData& stCfgData = CMainCtrl::m_pstMain->m_stPartnerMgr.GetPartnerCfg(iIndex);

        iGridPos = stMatrixList._astMatrixList[i]._chPos;

        iIndex = stRoleList._astRoleData.m_iUsedCount;
        ++stRoleList._astRoleData.m_iUsedCount;

        iRet = TransPartner(stPlayerBase, stPlayerDetail, stPlayerOnline,
            stActData, stPartner, stCfgData, stRoleList._astRoleData[iIndex],
            iGridPos, i, bIsLeft);
        CT_RETURN(iRet);
    }

    return 0;
}

int CBattleMgr::TransPartner(CPlayerBaseInfo& stPlayerBase,
        CPlayerDetailInfo& stPlayerDetail, CPlayerOnlineData& stPlayerOnline,
        CPartnerActData& stActData, CPartnerUnit& stPartner,
        CPartnerCfgData& stCfgData, CBattleRoleData& stRoleData,
        int iGridPos, unsigned char ucOrder, bool bIsLeft)
{
    int iRet = 0;
    stRoleData.Clear();//必须执行

    stRoleData._bAngerOpen = CMainCtrl::m_pstMain->m_stCommConfigLoader.IsOpen(
        SYS_OPEN_COND_ID_35, stPlayerBase, stPlayerOnline);

    stRoleData._bIsLeft = bIsLeft;
    stRoleData._bIsMale = stCfgData.GetIsMan();
    stRoleData._chType = GAME_OBJ_TYPE_PARTNER;
    stRoleData._iGridPos = iGridPos;
    stRoleData._ucOrder = ucOrder;
    stRoleData._ucCareer = stCfgData.GetCareer();
    stRoleData._shLevel = stActData._shLevel;
    stRoleData._iHP = stPartner._stAttr.GetAttr(EXT_ATTR_HP);
    stRoleData._iHPMax = stPartner._stAttr.GetAttr(EXT_ATTR_HP);
    stRoleData._iAnger = stPartner._stAttr.GetAttr(EXT_ATTR_ACT_ANGER);
    stRoleData._iAngerMax = MAX_ROLE_ANGER;
    stRoleData._iCourage = MAX_ROLE_COURAGE;
    stRoleData._iCourageMax = MAX_ROLE_COURAGE;

    stRoleData._uiObjID = stPartner._shResID;

    unsigned short usEquipCfgID = 0;
    for (int i = 0; i < stActData._stEquip._auiPartnerEquip.Size(); ++i)
    {
        if (stActData._stEquip._auiPartnerEquip[i] > 0)
        {
            iRet = CMainCtrl::m_pstMain->m_stEquipMgr.GetConfigIdByEquipId(
                    stActData._stEquip._auiPartnerEquip[i], usEquipCfgID);
            if (!iRet)
            {
                stRoleData._stEquip.SetEquip(usEquipCfgID, i+1);
            }
        }
    }

    stRoleData._stAttr = stPartner._stAttr;

    if (stPartner._stNormalSkill.GetID() > 0)
    {
        stRoleData._stNormalSkill = stPartner._stNormalSkill;
    }

    if (CMainCtrl::m_pstMain->m_stCommConfigLoader.IsOpen(SYS_OPEN_COND_ID_37,
            stPlayerBase, stPlayerOnline) &&
        stPartner._stMagicSkill.GetID() > 0)
    {
        stRoleData._stMagicSkill = stPartner._stMagicSkill;
        stRoleData._iAngerMax = stRoleData._stMagicSkill.GetUseAnger();
    }

    //状态列表:职业特性
    iRet = CMainCtrl::m_pstMain->m_stStatusMgr.GetStatusList(
            stCfgData.GetStatusGroupID(), stRoleData._stStatusList);
    CT_RETURN(iRet);

    //状态列表:秘宝
    CMainCtrl::m_pstMain->m_stTreasureMgr.GetTreasureStatusList(
        GAME_OBJ_TYPE_PARTNER, (unsigned int)stPartner._shResID,
        stPlayerDetail, stRoleData._stStatusList);

    return 0;
}

int CBattleMgr::TransGroupMonster(CMonsterGroupConfigData& stMonGroup,
        CBattleRoleList& stRoleList, bool bIsLeft)
{
    int iRet = 0;
    int iIndex = 0;
    stRoleList.Clear();//必须执行

    for (int i = 0; i < stMonGroup._astMonsters.Size(); ++i)
    {
        iIndex = stRoleList._astRoleData.m_iUsedCount;
        ++stRoleList._astRoleData.m_iUsedCount;
        iRet = TransMonster(stMonGroup._astMonsters[i],
            stRoleList._astRoleData[iIndex], bIsLeft);
        CT_RETURN(iRet);
    }

    return 0;
}

int CBattleMgr::TransMonster(CMonsterGroupMember& stMonMember,
        CBattleRoleData& stRoleData, bool bIsLeft)
{
    stRoleData.Clear();//必须执行

    int iRet = 0;
    stRoleData._bAngerOpen = true;
    stRoleData._bIsLeft = bIsLeft;
    stRoleData._chType = GAME_OBJ_TYPE_MONSTER;
    stRoleData._iGridPos = stMonMember._usPos;
    stRoleData._ucOrder = stMonMember._ucTurnOrder - 1;//怪物配置表中出手顺序从1开始这里作转换
    stRoleData._ucCareer = stMonMember._stMonster._ucCareer;
    stRoleData._shLevel = stMonMember._stMonster._usDefaultLevel;

    CMonsterAttrConfigData& stMonDefaultAttr = stMonMember._stMonster._stMonsterDefaultAttr;
    stRoleData._iHP = stMonDefaultAttr._uiHP;
    stRoleData._iHPMax = stMonDefaultAttr._uiHP;
    stRoleData._iAnger = stMonDefaultAttr._uiInitAnger;
    stRoleData._iAngerMax = MAX_ROLE_ANGER;
    stRoleData._iCourage = stMonDefaultAttr._uiInitCourage;
    stRoleData._iCourageMax = stMonDefaultAttr._uiInitCourage;
    stRoleData._iAngerRecRate = stMonDefaultAttr._uiAngerRecoverRate;
    stRoleData._iCourageRecRate = stMonDefaultAttr._uiCourageRecoverRate;

    stRoleData._uiObjID = stMonMember._uiMonsterID;

    stRoleData._stAttr.SetAttr(EXT_ATTR_HP, stMonDefaultAttr._uiHP);
    stRoleData._stAttr.SetAttr(EXT_ATTR_PHY_ATK, stMonDefaultAttr._uiPhyAtk);
    stRoleData._stAttr.SetAttr(EXT_ATTR_PHY_DEF, stMonDefaultAttr._uiPhyDef);
    stRoleData._stAttr.SetAttr(EXT_ATTR_MAG_ATK, stMonDefaultAttr._uiMagAtk);
    stRoleData._stAttr.SetAttr(EXT_ATTR_MAG_DEF, stMonDefaultAttr._uiMagDef);
    stRoleData._stAttr.SetAttr(EXT_ATTR_EARTH_ATK, stMonDefaultAttr._uiEarthAtk);
    stRoleData._stAttr.SetAttr(EXT_ATTR_WIND_ATK, stMonDefaultAttr._uiWaterAtk);
    stRoleData._stAttr.SetAttr(EXT_ATTR_FIRE_ATK, stMonDefaultAttr._uiFireAtk);
    stRoleData._stAttr.SetAttr(EXT_ATTR_WATER_ATK, stMonDefaultAttr._uiWindAtk);
    stRoleData._stAttr.SetAttr(EXT_ATTR_HIT, stMonDefaultAttr._uiHitLevel);
    stRoleData._stAttr.SetAttr(EXT_ATTR_DODGE, stMonDefaultAttr._uiDodgeLevel);
    stRoleData._stAttr.SetAttr(EXT_ATTR_DOUBLE, stMonDefaultAttr._uiDoubleLevel);
    stRoleData._stAttr.SetAttr(EXT_ATTR_ANTI_DOUBLE, stMonDefaultAttr._uiAntiDoubleLevel);
    stRoleData._stAttr.SetAttr(EXT_ATTR_BLOCK, stMonDefaultAttr._uiBlockLevel);
    stRoleData._stAttr.SetAttr(EXT_ATTR_ANTI_BLOCK, stMonDefaultAttr._uiAntiBlockLevel);
    stRoleData._stAttr.SetAttr(EXT_ATTR_TURN_ORDRE, stMonDefaultAttr._uiTurnOrderValue);
    stRoleData._stAttr.SetAttr(EXT_ATTR_CRIT, stMonDefaultAttr._uiCritLevel);
    stRoleData._stAttr.SetAttr(EXT_ATTR_FIGHT_BACK, stMonDefaultAttr._uiFightBackRate);
    stRoleData._stAttr.SetAttr(EXT_ATTR_IMMUNE_INJURY, stMonDefaultAttr._uiImmuneInjuryRate);
    stRoleData._stAttr.SetAttr(EXT_ATTR_REACT_INJURY, stMonDefaultAttr._uiReactInjuryRate);
    stRoleData._stAttr.SetAttr(EXT_ATTR_PENETRATE, stMonDefaultAttr._uiPenetrateRate);
    stRoleData._stAttr.SetAttr(EXT_ATTR_TREATMENT, stMonDefaultAttr._uiTreatmentRate);

    if (stMonMember._stMonster._uiNormalSkillID > 0)
    {
        iRet = CMainCtrl::m_pstMain->m_stSkillMgr.GetSkillByID(
                stRoleData._stNormalSkill,
                stMonMember._stMonster._uiNormalSkillID,
                CSkill::SKILL_TYPE_NORMAL);
        CT_RETURN(iRet);
    }

    if (stMonMember._stMonster._uiMagicSkillID > 0)
    {
        iRet = CMainCtrl::m_pstMain->m_stSkillMgr.GetSkillByID(
                stRoleData._stMagicSkill,
                stMonMember._stMonster._uiMagicSkillID,
                CSkill::SKILL_TYPE_MAGIC);
        CT_RETURN(iRet);

        stRoleData._iAngerMax = stRoleData._stMagicSkill.GetUseAnger();
    }

    //状态列表:职业特性
    iRet = CMainCtrl::m_pstMain->m_stStatusMgr.GetStatusList(
        stMonMember._stMonster._iStatusGroupID, stRoleData._stStatusList);
    CT_RETURN(iRet);

    return 0;
}

int CBattleMgr::AddPlayer(CPlayerBaseInfo& stPlayerBase,
        CPlayerDetailInfo& stPlayerDetail, CPlayerOnlineData& stPlayerOnline,
        bool bIsLeft)
{
    int iRet = 0;
    CBattleRoleData stRoleData;

    iRet = TransPlayer(stPlayerBase, stPlayerDetail, stPlayerOnline, stRoleData,
        bIsLeft);
    CT_RETURN(iRet);

    iRet = BATTLE_INF->_pstRoles->AddBattleRole(stRoleData);
    CT_RETURN(iRet);

    return 0;
}

int CBattleMgr::AddPartner(CPlayerBaseInfo& stPlayerBase,
        CPlayerDetailInfo& stPlayerDetail, CPlayerOnlineData& stPlayerOnline,
        bool bIsLeft)
{
    int iRet = 0;
    CBattleRoleList stRoleList;

    iRet = TransMatrixPartner(stPlayerBase, stPlayerDetail, stPlayerOnline,
        stRoleList, bIsLeft);
    CT_RETURN(iRet);

    for (int i = 0; i < stRoleList._astRoleData.Size(); ++i)
    {
        iRet = BATTLE_INF->_pstRoles->AddBattleRole(stRoleList._astRoleData[i]);
        CT_RETURN(iRet);
    }

    return 0;
}

int CBattleMgr::AddMonster(CMonsterGroupConfigData& stMonGroup, bool bIsLeft)
{
    CBattleRoleList stRoleList;

    int iRet = TransGroupMonster(stMonGroup, stRoleList, bIsLeft);
    CT_RETURN(iRet);

    for (int i = 0; i < stRoleList._astRoleData.Size(); ++i)
    {
        iRet = BATTLE_INF->_pstRoles->AddBattleRole(stRoleList._astRoleData[i]);
        CT_RETURN(iRet);
    }

    return 0;
}

int CBattleMgr::CheckBattleCoolingID(unsigned int uiGID)
{
    int iIndex = 0;

    iIndex = CMainCtrl::m_pstMain->m_stActMgr.FindActStatusCfg(
        ACT_ID_WORLD_BOSS);
    CT_CHECK(iIndex, ERROR_ACT_STATUS_EMPTY_CFG);
    
    CActStatusCfgData& stActStatusCfg =
        CMainCtrl::m_pstMain->m_stActMgr.GetActStatusCfg(iIndex);

    iIndex = CMainCtrl::m_pstMain->FindPlayerCacheData(uiGID);
    CT_CHECK(iIndex, 0);

	CPlayerCacheData& stPlayerCache =
        CMainCtrl::m_pstMain->m_stPlayerCacheDataHash[iIndex];

    iIndex = CMainCtrl::m_pstMain->m_stStatusMgr.FindStatus(
        stPlayerCache, stActStatusCfg.GetCoolingID());
    if (iIndex >= 0)
    {
        CStatusUnit& stStatusUnit =
            CMainCtrl::m_pstMain->m_stStatusMgr.GetStatus(
                stPlayerCache, iIndex);

        //战斗等待状态到期 先不主动清除 只判断时间
        if (stStatusUnit.GetEndTime() > CMainCtrl::m_pstMain->m_iNow)
        {
            return ERROR_STATUS_IN_FIGHT_CD;
        }
    }

    return 0;
}

int CBattleMgr::AddBattleCoolingID(unsigned int uiGID)
{
    int iRet = 0;
    int iIndex = 0;

    iIndex = CMainCtrl::m_pstMain->m_stActMgr.FindActStatusCfg(
        ACT_ID_WORLD_BOSS);
    CT_CHECK(iIndex, ERROR_ACT_STATUS_EMPTY_CFG);
    
    CActStatusCfgData& stActStatusCfg =
        CMainCtrl::m_pstMain->m_stActMgr.GetActStatusCfg(iIndex);

    iIndex = CMainCtrl::m_pstMain->FindPlayerCacheData(uiGID);
    CT_CHECK(iIndex, 0);

	CPlayerCacheData& stPlayerCache =
        CMainCtrl::m_pstMain->m_stPlayerCacheDataHash[iIndex];

    //战斗冷却没有叠加层数 直接修改到期时间
    iRet = CMainCtrl::m_pstMain->m_stStatusMgr.AddStatus(
        stPlayerCache, stActStatusCfg.GetCoolingID(),
        CMainCtrl::m_pstMain->m_iNow+CWorldBossMgr::WORLD_BOSS_FIGHT_WAIT_TIME,
        0, false);
    CT_RETURN(iRet);

    return 0;
}

int CBattleMgr::DealBattle(CPlayerBaseInfo& stPlayerBase,
        CPlayerDetailInfo& stPlayerDetail, CPlayerOnlineData& stPlayerOnline,
        CMonsterGroupConfigData& stMonGroup, MsgBattleResult& stMsgBattleRes,
        int iActType)
{
    int iRet = 0;

    /* 暂时去掉CD检查 by will
    iRet = CheckBattleCoolingID(stPlayerBase._uiGID);//PVE战斗CD检查
    CT_RETURN(iRet);
    */

    SetBattleActType(iActType);
    BATTLE_INF->_pstRoles->ClearRoleSize();//每场战斗之前都需要清

    //主角
    iRet = AddPlayer(stPlayerBase, stPlayerDetail, stPlayerOnline, true);
    CT_RETURN(iRet);

    //伙伴
    iRet = AddPartner(stPlayerBase, stPlayerDetail, stPlayerOnline, true);
    CT_RETURN(iRet);

    //怪物
    iRet = AddMonster(stMonGroup, false);
    CT_RETURN(iRet);

    iRet = ProcessBattle(stMsgBattleRes);
    CT_RETURN(iRet);

    /* 暂时去掉CD检查 by will
    iRet = AddBattleCoolingID(stPlayerBase._uiGID);//PVE战斗CD施加
    CT_RETURN(iRet);
    */

    return 0;
}

int CBattleMgr::AddPvPObj(unsigned int uiGID, bool bAddPartner, bool bIsLeft)
{
    int iRet = 0;
    int iIndex = 0;

    iIndex = CMainCtrl::m_pstMain->m_stPlayerBaseInfoHash.HashFind(uiGID);
    if (iIndex < 0)
	{
        CT_ERROR(("no base data user(%u)", uiGID));
        return ERROR_BATTLE_ADD_OBJECT;
	}
	CPlayerBaseInfo& stPlayerBase = CMainCtrl::m_pstMain->m_stPlayerBaseInfoHash[iIndex];

    iIndex = CMainCtrl::m_pstMain->m_stPlayerDetailInfoHash.HashFind(uiGID);
    if (iIndex < 0)
	{
        CT_ERROR(("no detail data user(%u)", uiGID));
        return ERROR_BATTLE_ADD_OBJECT;
	}
	CPlayerDetailInfo& stPlayerDetail = CMainCtrl::m_pstMain->m_stPlayerDetailInfoHash[iIndex];

    iIndex = CMainCtrl::m_pstMain->m_stPlayerOnlineDataHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("no online data user(%u)", uiGID));
        return ERROR_BATTLE_ADD_OBJECT;
    }
	CPlayerOnlineData& stPlayerOnline = CMainCtrl::m_pstMain->m_stPlayerOnlineDataHash[iIndex];

    //主角
    iRet = AddPlayer(stPlayerBase, stPlayerDetail, stPlayerOnline, bIsLeft);
    CT_RETURN(iRet);

    if (bAddPartner)
    {
        //伙伴
        iRet = AddPartner(stPlayerBase, stPlayerDetail, stPlayerOnline,
            bIsLeft);
        CT_RETURN(iRet);
    }

    return 0;
}

int CBattleMgr::DealPvPBattle(CBattlePvPData& stPvPData,
        MsgBattleResult& stMsgBattleRes, int iActType)
{
    int iRet = 0;
    int iLeftSize = stPvPData._auiLeftRole.Size();
    int iRightSize = stPvPData._auiRightRole.Size();
    bool bAddPartner = true;

    if (iLeftSize <= 0 && iRightSize <= 0)
    {
        CT_ERROR(("left role size(%d) right role size(%d)",
            iLeftSize,iRightSize));
        return ERROR_BATTLE_ADD_OBJECT;
    }

    if (iLeftSize > MAX_BATTLE_PVP_ROLES_COUNT ||
        iRightSize > MAX_BATTLE_PVP_ROLES_COUNT)
    {
        bAddPartner = false;
    }

    SetBattleActType(iActType);
    BATTLE_INF->_pstRoles->ClearRoleSize();//每场战斗之前都需要清

    for (int i = 0; i < iLeftSize; ++i)
    {
        iRet = AddPvPObj(stPvPData._auiLeftRole[i], bAddPartner, true);
        CT_RETURN(iRet);
    }

    for (int i = 0; i < iRightSize; ++i)
    {
        iRet = AddPvPObj(stPvPData._auiRightRole[i], bAddPartner, false);
        CT_RETURN(iRet);
    }

    iRet = ProcessBattle(stMsgBattleRes);
    CT_RETURN(iRet);

    return 0;
}

int CBattleMgr::DealPvPBattle(CBattleRoleList& stLeftRoleList,
        CBattleRoleList& stRightRoleList, MsgBattleResult& stMsgBattleRes,
        int iActType)
{
    int iRet = 0;
    int iBattleID = 0;

    SetBattleActType(iActType);
    BATTLE_INF->_pstRoles->ClearRoleSize();//每场战斗之前都需要清

    for (int i = 0; i < stLeftRoleList._astRoleData.Size(); ++i)
    {
        stLeftRoleList._astRoleData[i]._bIsLeft = true;
        if (stLeftRoleList._astRoleData[i].HasDead())
        {
            stLeftRoleList._astRoleData[i]._iBattleID = -1;//必须修改为非法值
            continue;
        }

        iRet = BATTLE_INF->_pstRoles->AddBattleRole(
            stLeftRoleList._astRoleData[i]);
        CT_RETURN(iRet);
    }

    for (int i = 0; i < stRightRoleList._astRoleData.Size(); ++i)
    {
        stRightRoleList._astRoleData[i]._bIsLeft = false;
        if (stRightRoleList._astRoleData[i].HasDead())
        {
            stRightRoleList._astRoleData[i]._iBattleID = -1;//必须修改为非法值
            continue;
        }

        iRet = BATTLE_INF->_pstRoles->AddBattleRole(
            stRightRoleList._astRoleData[i]);
        CT_RETURN(iRet);
    }

    iRet = ProcessBattle(stMsgBattleRes);
    CT_RETURN(iRet);

    for (int i = 0; i < stLeftRoleList._astRoleData.Size(); ++i)
    {
        iBattleID = stLeftRoleList._astRoleData[i]._iBattleID;
        if (iBattleID >= 0 && iBattleID < BATTLE_INF->_pstRoles->GetRoleCount())
        {
            stLeftRoleList._astRoleData[i] =
                BATTLE_INF->_pstRoles->GetRoleBase(iBattleID);
            stLeftRoleList._astRoleData[i]._iBattleID = iBattleID;
        }
    }

    for (int i = 0; i < stRightRoleList._astRoleData.Size(); ++i)
    {
        iBattleID = stRightRoleList._astRoleData[i]._iBattleID;
        if (iBattleID >= 0 && iBattleID < BATTLE_INF->_pstRoles->GetRoleCount())
        {
            stRightRoleList._astRoleData[i] =
                BATTLE_INF->_pstRoles->GetRoleBase(iBattleID);
            stRightRoleList._astRoleData[i]._iBattleID = iBattleID;
        }
    }

    return 0;
}

int CBattleMgr::DealWorldBoss(CPlayerBaseInfo& stPlayerBase,
        CPlayerDetailInfo& stPlayerDetail, CPlayerOnlineData& stPlayerOnline,
        CMonsterGroupConfigData& stMonGroup, MsgBattleResult& stMsgBattleRes,
        int iActType)
{
    int iRet = 0;
    int iIndex = 0;

    SetBattleActType(iActType);
    BATTLE_INF->_pstRoles->ClearRoleSize();//每场战斗之前都需要清

    CBattleRoleList stRoleList;
    iRet = TransPlayerAndPartner(stPlayerBase, stPlayerDetail, stPlayerOnline,
            stRoleList, true);
    CT_RETURN(iRet);

    for (int i = 0; i < stRoleList._astRoleData.Size(); ++i)
    {
        iRet = BATTLE_INF->_pstRoles->AddBattleRole(stRoleList._astRoleData[i]);
        CT_RETURN(iRet);
    }

    //怪物
    int iMonBattleID = BATTLE_INF->_pstRoles->GetRoleCount();
    if (stMonGroup._astMonsters.Size() > 0)
    {
        CBattleRoleData stRoleDataTmp;
        iRet = TransMonster(stMonGroup._astMonsters[0], stRoleDataTmp, false);
        CT_RETURN(iRet);
        
        iRet = BATTLE_INF->_pstRoles->AddBattleRole(stRoleDataTmp);
        CT_RETURN(iRet);
    }

    if (BATTLE_INF->_pstRoles->GetRoleCount() <= iMonBattleID)
    {
        //加载怪物失败
        CT_ERROR(("Add Monster Fail!"));
        return ERROR_BATTLE_ADD_OBJECT;
    }

    iIndex = CMainCtrl::m_pstMain->m_stActMgr.FindActCfg(ACT_ID_WORLD_BOSS);
    CT_CHECK(iIndex, ERROR_ACT_EMPTY_CFG);
    CActCfgData& stBoss = CMainCtrl::m_pstMain->m_stActMgr.GetActCfg(iIndex);

    iIndex = CMainCtrl::m_pstMain->m_stActMgr.FindActCfg(ACT_ID_GRAN_BOSS);
    CT_CHECK(iIndex, ERROR_ACT_EMPTY_CFG);
    CActCfgData& stGran = CMainCtrl::m_pstMain->m_stActMgr.GetActCfg(iIndex);

    iIndex = CMainCtrl::m_pstMain->m_stActMgr.FindActCfg(ACT_ID_SLEN_BOSS);
    CT_CHECK(iIndex, ERROR_ACT_EMPTY_CFG);
    CActCfgData& stSlen = CMainCtrl::m_pstMain->m_stActMgr.GetActCfg(iIndex);
#if 0
    iIndex = CMainCtrl::m_pstMain->m_stActMgr.FindActCfg(ACT_ID_RAVAN_BOSS);
    CT_CHECK(iIndex, ERROR_ACT_EMPTY_CFG);
    CActCfgData& stRavan = CMainCtrl::m_pstMain->m_stActMgr.GetActCfg(iIndex);

    iIndex = CMainCtrl::m_pstMain->m_stActMgr.FindActCfg(ACT_ID_HUFF_BOSS);
    CT_CHECK(iIndex, ERROR_ACT_EMPTY_CFG);
    CActCfgData& stHuff = CMainCtrl::m_pstMain->m_stActMgr.GetActCfg(iIndex);
#endif
    iIndex = CMainCtrl::m_pstMain->m_stActMgr.FindActCfg(ACT_ID_MAGIC_DOOR);
    CT_CHECK(iIndex, ERROR_ACT_EMPTY_CFG);
    CActCfgData& stDoor = CMainCtrl::m_pstMain->m_stActMgr.GetActCfg(iIndex);

    //修正世界BOSS相关数据
    if (stBoss.GetType() == _iActType)
    {
        iRet = CMainCtrl::m_pstMain->m_stWorldBossMgr.ReviseBeforeBattle(
            iMonBattleID);
        CT_RETURN(iRet);
    }
    //修正学院BOSS相关数据
    else if (stGran.GetType() == _iActType || stSlen.GetType() == _iActType)
#if 0
    else if (stGran.GetType() == _iActType || stSlen.GetType() == _iActType ||
             stRavan.GetType() == _iActType || stHuff.GetType() == _iActType)
#endif
    { 
        iRet = CMainCtrl::m_pstMain->m_stAcademyBossMgr.ReviseBeforeBattle(
            iMonBattleID);
        CT_RETURN(iRet);
    }
    //修正魔界传送门相关数据
    else if (stDoor.GetType() == _iActType)
    {
        iRet = CMainCtrl::m_pstMain->m_stMagicDoorMgr.ReviseBeforeBattle(
            iMonBattleID);
        CT_RETURN(iRet);
    }
    else
    {
        CT_ERROR(("Unknow boss battle type(%d)",iActType));
    }
      
    iRet = ProcessBattle(stMsgBattleRes);
    CT_RETURN(iRet);

    return 0;
}

int CBattleMgr::SkillPreEffectDataCalc(int& iPreData, int iBase,
        CSkillEffect& stSkillEffect)
{
    return _stRules.SkillPreEffectDataCalc(iPreData, iBase, stSkillEffect);
}

void CBattleMgr::GetBattleVideoKey(unsigned int uiGID, int iTypeID,
        T_VIDEO_KEY& szVideoKey)
{
    CMainCtrl* pstMainCtrl = CMainCtrl::m_pstMain;
    szVideoKey.Set("%d_%u_%d_%d_%d", pstMainCtrl->ZoneID(), uiGID, iTypeID, pstMainCtrl->m_iNow, 
        CT_RANDOM_NUM->GetRand(pstMainCtrl->m_iNow + pstMainCtrl->m_stNowTime.tv_usec));

    CT_BATTLE(("BattleVideoKey=%s",szVideoKey.Get()));
}

//调试用 输出日志
void CBattleMgr::DumpPlayerAttr(CPlayerAttr& stRoleAttr)
{
    CT_BATTLE(("%-18s = %d", "生命", stRoleAttr.GetAttr(EXT_ATTR_HP)));
    CT_BATTLE(("%-18s = %d", "物攻", stRoleAttr.GetAttr(EXT_ATTR_PHY_ATK)));
    CT_BATTLE(("%-18s = %d", "物防", stRoleAttr.GetAttr(EXT_ATTR_PHY_DEF)));
    CT_BATTLE(("%-18s = %d", "魔攻", stRoleAttr.GetAttr(EXT_ATTR_MAG_ATK)));
    CT_BATTLE(("%-18s = %d", "魔防", stRoleAttr.GetAttr(EXT_ATTR_MAG_DEF)));
    CT_BATTLE(("%-18s = %d", "地攻", stRoleAttr.GetAttr(EXT_ATTR_EARTH_ATK)));
    CT_BATTLE(("%-18s = %d", "风攻", stRoleAttr.GetAttr(EXT_ATTR_WIND_ATK)));
    CT_BATTLE(("%-18s = %d", "火攻", stRoleAttr.GetAttr(EXT_ATTR_FIRE_ATK)));
    CT_BATTLE(("%-18s = %d", "水攻", stRoleAttr.GetAttr(EXT_ATTR_WATER_ATK)));
    CT_BATTLE(("%-18s = %d", "命中", stRoleAttr.GetAttr(EXT_ATTR_HIT)));
    CT_BATTLE(("%-18s = %d", "闪避", stRoleAttr.GetAttr(EXT_ATTR_DODGE)));
    CT_BATTLE(("%-18s = %d", "暴击", stRoleAttr.GetAttr(EXT_ATTR_DOUBLE)));
    CT_BATTLE(("%-18s = %d", "抗暴", stRoleAttr.GetAttr(EXT_ATTR_ANTI_DOUBLE)));
    CT_BATTLE(("%-18s = %d", "格挡", stRoleAttr.GetAttr(EXT_ATTR_BLOCK)));
    CT_BATTLE(("%-18s = %d", "破击", stRoleAttr.GetAttr(EXT_ATTR_ANTI_BLOCK)));
    CT_BATTLE(("%-18s = %d", "出手速度", stRoleAttr.GetAttr(EXT_ATTR_TURN_ORDRE)));
    CT_BATTLE(("%-18s = %d", "必杀", stRoleAttr.GetAttr(EXT_ATTR_CRIT)));
    CT_BATTLE(("%-18s = %d", "免伤", stRoleAttr.GetAttr(EXT_ATTR_IMMUNE_INJURY)));
    CT_BATTLE(("%-18s = %d", "反伤", stRoleAttr.GetAttr(EXT_ATTR_REACT_INJURY)));
    CT_BATTLE(("%-18s = %d", "穿透", stRoleAttr.GetAttr(EXT_ATTR_PENETRATE)));
    CT_BATTLE(("%-18s = %d", "痊愈", stRoleAttr.GetAttr(EXT_ATTR_TREATMENT)));
    CT_BATTLE(("%-18s = %d", "反击", stRoleAttr.GetAttr(EXT_ATTR_FIGHT_BACK)));
}
